/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.ts.service.impl;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import com.xy.biz.ts.cons.ExaminationQuestionConstant;
import com.xy.biz.ts.cons.ExaminationRecordConstant;
import com.xy.biz.ts.domain.bo.*;
import com.xy.biz.ts.domain.converter.ExaminationRecordConverter;
import com.xy.biz.ts.domain.converter.ExaminationRecordQuestionConverter;
import com.xy.biz.ts.domain.query.ExaminationRecordQuestionQuery;
import com.xy.biz.ts.domain.query.TrainQuery;
import com.xy.biz.ts.domain.req.SaveExaminationRecordRequest;
import com.xy.biz.ts.domain.req.examinationRecord.GetExaminationRecordByTrainIdRequest;
import com.xy.biz.ts.domain.resp.GetExaminationRecordQuestionResponse;
import com.xy.biz.ts.domain.resp.GetExaminationRecordResponse;
import com.xy.biz.ts.domain.resp.PreviewExaminationPaperResponse;
import com.xy.biz.ts.manager.*;
import com.xy.biz.ts.service.ExaminationPaperService;
import com.xy.biz.uc.client.UserClient;
import com.xy.tool.context.UserContextHolder;
import com.xy.tool.json.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xy.lang.domain.Result;
import com.xy.biz.ts.domain.query.ExaminationRecordQuery;
import com.xy.biz.ts.service.ExaminationRecordService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 *
 *
 * @author wcs
 * @date 2021-3-10
 */
@Service
public class ExaminationRecordServiceImpl implements ExaminationRecordService {


    @Autowired
    private ExaminationRecordManager examinationRecordManager;

    @Autowired
    private ExaminationPaperManager examinationPaperManager;

    @Autowired
    private ExaminationQuestionManager examinationQuestionManager;

    @Autowired
    private ExaminationRecordQuestionManager examinationRecordQuestionManager;

    @Autowired
    private ExaminationPaperService examinationPaperService;

    @Autowired
    private UserClient userClient;

    @Autowired
    private TrainManager trainManager;


    @Transactional
    @Override
    public Result<?> saveExaminationRecord(SaveExaminationRecordRequest request) {
        String saveData = request.getSaveData();
        Map parse = JsonUtils.parse(saveData, Map.class);
        //试卷id
        Long examinationPaperId = Long.parseLong(parse.get("examinationPaperId").toString());
        //获取试卷信息
        ExaminationPaperBO examinationPaper = examinationPaperManager.getExaminationPaper(examinationPaperId);
        //定义考试记录实体类
        LocalDateTime now = LocalDateTime.now();
        ExaminationRecordBO examinationRecordBO = ExaminationRecordBO.builder()
                .examinationPaperId(examinationPaperId)
                .trainId(Long.parseLong(parse.get("trainId") + ""))
                .examinationPaperCategory(examinationPaper.getCategory())
                .examinationPaperName(examinationPaper.getExaminationPaperName())
                .examineeUserGroupId(UserContextHolder.getUserGroupId())
                .examineeUserGroupName(UserContextHolder.getUserGroupName())
                .examineeUserId(UserContextHolder.getUserId())
                .examineeUserName(UserContextHolder.getUserName())
                .examineeTime(LocalDateTime.parse(parse.get("examineeTime").toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                .handInTime(now)
                .totalScore(examinationPaper.getTotalScore())
                .passScore(examinationPaper.getPassScore())
                .score(0)
                .passFlag(0)
                .createUserId(UserContextHolder.getUserId())
                .createTime(now)
                .updateTime(now)
                .tenantId(0L)
                .commentUserId(0L)
                .build();
        //添加考试记录
        examinationRecordBO = examinationRecordManager.saveExaminationRecord(examinationRecordBO);

        //试题答案集合
        List<ExaminationRecordQuestionBO> examinationRecordQuestionBOSAlreadyEdited = new ArrayList<>();

        List<ExaminationRecordQuestionBO> examinationRecordQuestionBOSUnmodified = new ArrayList<>();
        //试题答案
        Map<String, String> questionDataList = (Map) parse.get("questionDataList");
        if (Objects.isNull(questionDataList)) {
            return Result.ofErrorRowsAffected();
        }
        //查询试题
        Set<Long> collect = questionDataList.keySet().stream().map(item -> Long.parseLong(item.substring(0, item.length() - 3))).collect(Collectors.toSet());
        List<ExaminationQuestionBO> examinationQuestionBOS = examinationQuestionManager.listExaminationQuestionById(collect);
        //得到所有试题
        Map<Long, ExaminationQuestionBO> collect1 = examinationQuestionBOS.stream().collect(Collectors.toMap(ExaminationQuestionBO::getExaminationQuestionId, ExaminationQuestionBO -> ExaminationQuestionBO));

        ExaminationRecordBO finalExaminationRecordBO = examinationRecordBO;
        for (String key : questionDataList.keySet()) {
            long examinationQuestionId = Long.parseLong(key.substring(0, key.length() - 3));
            String answer = questionDataList.get(key);
            if (Objects.isNull(answer)) {
                return Result.ofErrorData("不可留空题，请完善试卷！");
            }
            ExaminationRecordQuestionBO examinationRecordQuestionBO = ExaminationRecordQuestionBO.builder()
                    .examinationRecordId(examinationRecordBO.getExaminationRecordId())
                    .examinationQuestionId(examinationQuestionId)
                    .factAnswer(answer)
                    .tenantId(0L)
                    .build();
            ExaminationQuestionBO examinationQuestionBO = collect1.get(examinationQuestionId);

            examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_ERR);
            examinationRecordQuestionBO.setFactScore(0);
            //判断题，单选题答案唯一
            if (examinationQuestionBO.getType() == ExaminationQuestionConstant.TYPE_JUDGMENT
                    || examinationQuestionBO.getType() == ExaminationQuestionConstant.TYPE_SINGLE_CHOICE) {
                if (examinationQuestionBO.getAnswer().equals(answer)) {
                    examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_RIGHT);
                    examinationRecordQuestionBO.setFactScore(examinationQuestionBO.getScore());
                    examinationRecordQuestionBO.setGraded(ExaminationQuestionConstant.GRADED_YES);
                } else {
                    examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_ERR);
                    examinationRecordQuestionBO.setFactScore(0);
                    examinationRecordQuestionBO.setGraded(ExaminationQuestionConstant.GRADED_YES);
                }
                examinationRecordQuestionBOSAlreadyEdited.add(examinationRecordQuestionBO);
                continue;
            }

            //判断多选题
            if (examinationQuestionBO.getType() == ExaminationQuestionConstant.TYPE_MULTIPLE_CHOICE) {
                String[] split = examinationQuestionBO.getAnswer().split(",");//正确答案
                String[] split1 = questionDataList.get(key).split(",");//输入的答案
                Arrays.sort(split);
                Arrays.sort(split1);
                if (Arrays.equals(split, split1)) {
                    examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_RIGHT);
                    examinationRecordQuestionBO.setFactScore(examinationQuestionBO.getScore());
                    examinationRecordQuestionBO.setGraded(ExaminationQuestionConstant.GRADED_YES);
                } else {
                    examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_ERR);
                    examinationRecordQuestionBO.setFactScore(0);
                    examinationRecordQuestionBO.setGraded(ExaminationQuestionConstant.GRADED_YES);
                }
                examinationRecordQuestionBOSAlreadyEdited.add(examinationRecordQuestionBO);
                continue;
            }

            //判断填空题
            if (examinationQuestionBO.getType() == ExaminationQuestionConstant.TYPE_FILL_AVACANCY) {
                String thisAnswer = examinationQuestionBO.getAnswer().toLowerCase();//正确答案
                String data = questionDataList.get(key).toLowerCase();//输入的答案

                if (Objects.equals(thisAnswer, data)) {
                    examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_RIGHT);
                    examinationRecordQuestionBO.setFactScore(examinationQuestionBO.getScore());
                    examinationRecordQuestionBO.setGraded(ExaminationQuestionConstant.GRADED_YES);
                } else {
                    examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_ERR);
                    examinationRecordQuestionBO.setFactScore(0);
                    examinationRecordQuestionBO.setGraded(ExaminationQuestionConstant.GRADED_YES);
                }
                examinationRecordQuestionBOSAlreadyEdited.add(examinationRecordQuestionBO);
                continue;
            }
            examinationRecordQuestionBOSUnmodified.add(examinationRecordQuestionBO);
        }
        //已修改的
        if (examinationRecordQuestionBOSAlreadyEdited.size() > 0) {
            int row = examinationRecordQuestionManager.saveAllExaminationRecordQuestion(examinationRecordQuestionBOSAlreadyEdited);

        }
        if (examinationRecordQuestionBOSUnmodified.size() > 0) {
            //未修改的
            int row = examinationRecordQuestionManager.saveAllExaminationRecordQuestionUnmodified(examinationRecordQuestionBOSUnmodified);
        }
        return Result.success();
    }


    @Override
    public Result<?> saveAllExaminationRecord(Collection<ExaminationRecordBO> collection) {
        int affectedRows = examinationRecordManager.saveAllExaminationRecord(collection);
        if (affectedRows > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public Result<?> updateExaminationRecord(ExaminationRecordBO examinationRecordBO) {
        int affectedRows = examinationRecordManager.updateExaminationRecord(examinationRecordBO);
        if (affectedRows > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public Result<?> deleteExaminationRecord(Long examinationRecordId) {
        int affectedRows = examinationRecordManager.deleteExaminationRecord(examinationRecordId);
        if (affectedRows > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public Result<?> getExaminationRecord(Long examinationRecordId) {
        //查询试卷记录
        ExaminationRecordBO examinationRecordBO = examinationRecordManager.getExaminationRecord(examinationRecordId);
        //转换为响应类
        GetExaminationRecordResponse getExaminationRecordResponse = ExaminationRecordConverter.toResponse(examinationRecordBO);
        //定义试卷试题信息查询
        ExaminationRecordQuestionQuery query = ExaminationRecordQuestionQuery.max().examinationRecordId(examinationRecordId).build();
        //试卷试题信息列表
        List<ExaminationRecordQuestionBO> examinationRecordQuestionBOS = examinationRecordQuestionManager.listExaminationRecordQuestion(query);
        //考试记录试题信息转换为响应类
        List<GetExaminationRecordQuestionResponse> getExaminationRecordQuestionResponses = ExaminationRecordQuestionConverter.toResponse(examinationRecordQuestionBOS);
        //考试记录试题信息转map
        Map<Long, GetExaminationRecordQuestionResponse> collect = getExaminationRecordQuestionResponses.stream().collect(Collectors.toMap(GetExaminationRecordQuestionResponse::getExaminationQuestionId, GetExaminationRecordQuestionResponse -> GetExaminationRecordQuestionResponse));
        //传入前台的试题答案信息
        getExaminationRecordResponse.setGetExaminationRecordQuestionResponses(collect);
        //试卷试题渲染
        PreviewExaminationPaperResponse previewExaminationPaperResponse = examinationPaperService.previewExaminationPaper(examinationRecordBO.getExaminationPaperId());
        //试卷试题渲染封装
        getExaminationRecordResponse.setPreviewExaminationPaperResponse(previewExaminationPaperResponse);
        return Result.success(getExaminationRecordResponse);
    }

    /**
     * 根据TrainId查找
     *
     * @param request
     * @return
     */
    @Override
    public List<GetExaminationRecordResponse> listExaminationRecordByTrainId(GetExaminationRecordByTrainIdRequest request) {
        List<ExaminationRecordBO> examinationRecordBOS = examinationRecordManager.listExaminationRecord(ExaminationRecordQuery.max().trainIds(request.getTrainIds()).build());
        return ExaminationRecordConverter.toResponse(examinationRecordBOS);
    }

    @Override
    public List<ExaminationRecordBO> listExaminationRecordById(Collection<Long> collection) {
        return examinationRecordManager.listExaminationRecordById(collection);
    }

    @Override
    public List<ExaminationRecordBO> listExaminationRecord(ExaminationRecordQuery query) {

        List<ExaminationRecordBO> recordBOList = examinationRecordManager.listExaminationRecord(query);
        recordBOList.forEach(e -> e.setTimeConsuming(buildTime(e.getExamineeTime(), e.getHandInTime())));

        return recordBOList;
    }

    @Override
    public List<GetExaminationRecordResponse> listExaminationRecord1(ExaminationRecordQuery query) {
        List<ExaminationRecordBO> recordBOList = examinationRecordManager.listExaminationRecord(query);
        if (CollectionUtils.isEmpty(recordBOList)) {
            return Collections.emptyList();
        }
        return ExaminationRecordConverter.toResponse(recordBOList);
    }

    private String buildTime(LocalDateTime examineeTime, LocalDateTime handInTime) {
        long milli = ChronoUnit.MILLIS.between(examineeTime, handInTime);
        SimpleDateFormat formatter = new SimpleDateFormat("HH时mm分ss秒");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
        return formatter.format(milli);
    }

    @Override
    public int countExaminationRecord(ExaminationRecordQuery query) {
        return examinationRecordManager.countExaminationRecord(query);
    }

    @Transactional
    @Override
    public Result<?> correctExaminationRecord(SaveExaminationRecordRequest request) {
        String saveData = request.getSaveData();
        Map parse = JsonUtils.parse(saveData, Map.class);
        Long examinationRecordId = Long.parseLong(parse.get("examinationRecordId").toString());
        Map<String, String> questionDataList = (Map<String, String>) parse.get("questionDataList");
        String comment = String.valueOf(parse.get("comment"));
        //批量修改试题分数
        List<ExaminationRecordQuestionBO> examinationRecordQuestionBOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(questionDataList)) {
            for (String key : questionDataList.keySet()) {
                Integer score = Integer.parseInt(questionDataList.get(key));
                ExaminationRecordQuestionBO examinationRecordQuestionBO = new ExaminationRecordQuestionBO();
                examinationRecordQuestionBO.setExaminationRecordQuestionId(Long.parseLong(key.substring(0, key.length() - 3)));
                examinationRecordQuestionBO.setFactScore(score);
                examinationRecordQuestionBO.setGraded(ExaminationQuestionConstant.GRADED_YES);
                examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_RIGHT);
                if (score == 0) {
                    examinationRecordQuestionBO.setResultFlag(ExaminationQuestionConstant.RESULT_FLAG_ERR);
                }
                examinationRecordQuestionBOS.add(examinationRecordQuestionBO);
            }
            int row = examinationRecordQuestionManager.updateExaminationRecordQuestionList(examinationRecordQuestionBOS);
            if (row == 0) {
                return Result.ofErrorRowsAffected();
            }
        }

        //修改试卷数据
        ExaminationRecordBO examinationRecord = examinationRecordManager.getExaminationRecord(examinationRecordId);
        List<ExaminationRecordQuestionBO> examinationRecordQuestionBOList = examinationRecordQuestionManager.listExaminationRecordQuestion(ExaminationRecordQuestionQuery.max().examinationRecordId(examinationRecordId).build());
        int score = examinationRecordQuestionBOList.stream().mapToInt(ExaminationRecordQuestionBO::getFactScore).sum();
        if (score > examinationRecord.getPassScore()) {
            examinationRecord.setPassFlag(ExaminationRecordConstant.PASS_FLAG_QUALIFIED);
        } else {
            examinationRecord.setPassFlag(ExaminationRecordConstant.PASS_FLAG_DISQUALIFICATION);
        }
        examinationRecord.setScore(score);
        examinationRecord.setComment(StringUtils.isEmpty(comment) ? "无" : comment);
        examinationRecord.setCommentUserId(UserContextHolder.getUserId());
        examinationRecord.setUpdateTime(LocalDateTime.now());
        int row = examinationRecordManager.updateExaminationRecord(examinationRecord);
        if (row == 0) {
            return Result.ofErrorRowsAffected();
        }
        return Result.success();
    }

}
